﻿using System.Buffers;
using System.Collections.Generic;
using Xc.DataAccess.Core.Extensions;
using System.Linq;
using System.Text.Json.Serialization;
using Xc.DataAccess.Protocoals.WaterMeters.Extensions;
using Microsoft.Extensions.DependencyInjection;

namespace Xc.DataAccess.Protocoals.WaterMeters.Models
{
    /// <summary>
    /// 表计数据抽象类
    /// </summary>
    public abstract class MeterFrameRxDataSegmentBase : MeterFrameRxBase
    {
        public MeterFrameRxDataSegmentBase(MeterFrameRx dataArea) : base(dataArea)
        {
        }

        protected MeterFrameRxDataSegmentBase()
        {
        }
        /// <summary>
        /// 命令类型唯一码
        /// </summary>
        [JsonPropertyName("Index")]
        public uint Index 
        {
            get
            {
                var key = (uint)(((byte)Cmd) * 0x10000 + (ushort)DataSegment);
                return key;
            }
        }
        protected override bool SetDataArea(DataArea dataArea)
        {
            if (dataArea==null)
            {
                return false;
            }
            var res = true;
            if (ValidateCmd.All(s=>s!=Cmd))
            {
                res= false;
            }
            SequenceReader<byte> sequenceReader = new SequenceReader<byte>(new ReadOnlySequence<byte>(dataArea.Data));
            if (!sequenceReader.TryRead(2,out ReadOnlySequence<byte> datasegment))
            {
                res = false;
            }
            DataSegment = (DataSegment)datasegment.ToArray().ToUInt16LittleEndian();
            if (ValidateDataSegment!=DataSegment)
            {
                res = false;
            }
            if (!sequenceReader.TryRead(out byte companyId))
            {
                res = false;
            }
            CompanyId = companyId;
            if (res==false)
            {
                return false;
            }
            if (!dataArea.IsValidate)
            {
                return false;
            }
            return SetData(ref sequenceReader);
        }
        /// <summary>
        /// 验证CMD
        /// </summary>
        /// <returns></returns>
        [JsonIgnore]
        internal abstract IEnumerable<FrameCommand> ValidateCmd { get; }

        /// <summary>
        /// 数据段是否合法
        /// </summary>
        /// <param name="res"></param>
        /// <returns></returns>
        [JsonIgnore]
        internal abstract DataSegment ValidateDataSegment { get; }

        /// <summary>
        /// 设置数据域数据
        /// </summary>
        /// <param name="sequenceReader"></param>
        protected abstract bool SetData(ref SequenceReader<byte> sequenceReader);
        /// <summary>
        /// 数据标识
        /// </summary>
        public DataSegment DataSegment { get; set; }
        /// <summary>
        /// 厂商ID
        /// </summary>
        public byte CompanyId { get; set; }
    }

}
